#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义火车车次结构体
typedef struct Train {
    char number[20];       // 车次
    char start[20];        // 始发站
    char end[20];          // 终点站
    char start_time[20];   // 发车时间
    char arrive_time[20];  // 到站时间
    float price;           // 票价
    int tickets;           // 剩余票数
    struct Train* next;    // 链表指针
} Train;

// 定义订票信息结构体
typedef struct Order {
    char train_number[20]; // 所订车次
    char passenger[20];    // 乘客姓名
    char id[20];           // 身份证号
    char phone[20];        // 联系电话
    struct Order* next;    // 链表指针
} Order;


// 全局变量
Train* train_head = NULL;  // 火车信息链表头指针
Order* order_head = NULL;  // 订单信息链表头指针

// 函数声明
void addTrain();           // 添加火车信息
void searchTrain();        // 查询火车信息
void bookTicket();         // 订票
void modifyTrain();        // 修改火车信息
void showTrains();         // 显示所有火车信息
void saveData();           // 保存数据到文件
void loadData();           // 从文件加载数据
void showMenu();           // 显示菜单

// 添加火车信息
void addTrain() {
    Train* new_train = (Train*)malloc(sizeof(Train));
    if (new_train == NULL) {
        printf("内存分配失败！\n");
        return;
    }

    printf("请输入车次：");
    scanf("%s", new_train->number);

    // 检查车次是否已存在
    Train* current = train_head;
    while (current != NULL) {
        if (strcmp(current->number, new_train->number) == 0) { //通过strcmp函数判断车次是否相同
            printf("该车次已存在！\n");
            free(new_train);
            return;
        }
        current = current->next;
    }

    printf("请输入始发站：");
    scanf("%s", new_train->start);
    printf("请输入终点站：");
    scanf("%s", new_train->end);
    printf("请输入发车时间：");
    scanf("%s", new_train->start_time);
    printf("请输入到站时间：");
    scanf("%s", new_train->arrive_time);
    printf("请输入票价：");
    scanf("%f", &new_train->price);
    printf("请输入剩余票数：");
    scanf("%d", &new_train->tickets);

    // 插入到链表头部
    new_train->next = train_head;
    train_head = new_train;

    printf("火车信息添加成功！\n");
    saveData();  // 保存数据
}

// 查询火车信息
void searchTrain() {
    int choice;
    printf("请选择查询方式：\n");
    printf("1. 按车次查询\n");
    printf("2. 按城市查询\n");
    scanf("%d", &choice);

    if (choice == 1) {
        char number[20];
        printf("请输入要查询的车次：");
        scanf("%s", number);

        Train* current = train_head;
        int found = 0;
        while (current != NULL) {
            if (strcmp(current->number, number) == 0) {
                printf("车次：%s\n", current->number);
                printf("始发站：%s\n", current->start);
                printf("终点站：%s\n", current->end);
                printf("发车时间：%s\n", current->start_time);
                printf("到站时间：%s\n", current->arrive_time);
                printf("票价：%.2f\n", current->price);
                printf("剩余票数：%d\n", current->tickets);
                found = 1;
                break;
            }
            current = current->next;
        }

        if (!found) {
            printf("未找到该车次！\n");
        }
    } else if (choice == 2) {
        char city[20];
        printf("请输入要查询的城市：");
        scanf("%s", city);

        Train* current = train_head;
        int found = 0;
        printf("经过 %s 的车次信息：\n", city);
        while (current != NULL) {
            if (strcmp(current->start, city) == 0 || strcmp(current->end, city) == 0) {
                printf("车次：%s\n", current->number);
                printf("始发站：%s\n", current->start);
                printf("终点站：%s\n", current->end);
                printf("发车时间：%s\n", current->start_time);
                printf("到站时间：%s\n", current->arrive_time);
                printf("票价：%.2f\n", current->price);
                printf("剩余票数：%d\n", current->tickets);
                printf("------------------------\n");
                found = 1;
            }
            current = current->next;
        }

        if (!found) {
            printf("未找到相关车次！\n"); 
        }
    } else {
        printf("无效的选择！\n");
    }
}

// 订票
void bookTicket() {
    char city[20];
    printf("请输入目的地城市：");
    scanf("%s", city);

    // 显示符合条件的车次
    Train* current = train_head;
    int found = 0;
    printf("前往 %s 的车次信息：\n", city);
    while (current != NULL) {
        if (strcmp(current->end, city) == 0) {
            printf("车次：%s\n", current->number);
            printf("始发站：%s\n", current->start);
            printf("终点站：%s\n", current->end);
            printf("发车时间：%s\n", current->start_time);
            printf("到站时间：%s\n", current->arrive_time);
            printf("票价：%.2f\n", current->price);
            printf("剩余票数：%d\n", current->tickets);
            printf("------------------------\n");
            found = 1;
        }
        current = current->next;
    }

    if (!found) {
        printf("未找到前往该城市的车次！\n");
        return;
    }

    char train_number[20];
    printf("请输入要预订的车次：");
    scanf("%s", train_number);

    current = train_head;
    Train* selected_train = NULL;
    while (current != NULL) {
        if (strcmp(current->number, train_number) == 0 && strcmp(current->end, city) == 0) {
            selected_train = current;
            break;
        }
        current = current->next;
    }

    if (selected_train == NULL) {
        printf("无效的车次选择！\n");
        return;
    }

    if (selected_train->tickets <= 0) {
        printf("该车次已无余票！\n");
        return;
    }

    // 创建新订单
    Order* new_order = (Order*)malloc(sizeof(Order));
    if (new_order == NULL) {
        printf("内存分配失败！\n");
        return;
    }

    strcpy(new_order->train_number, train_number);
    printf("请输入乘客姓名：");
    scanf("%s", new_order->passenger);
    printf("请输入身份证号：");
    scanf("%s", new_order->id);
    printf("请输入联系电话：");
    scanf("%s", new_order->phone);

    // 插入到订单链表
    new_order->next = order_head;
    order_head = new_order;

    // 更新车票数量
    selected_train->tickets--;

    printf("订票成功！\n");
    printf("订单信息：\n");
    printf("车次：%s\n", new_order->train_number);
    printf("乘客姓名：%s\n", new_order->passenger);
    printf("身份证号：%s\n", new_order->id);
    printf("联系电话：%s\n", new_order->phone);

    saveData();  // 保存数据
}

// 修改火车信息
void modifyTrain() {
    char number[20];
    printf("请输入要修改的车次：");
    scanf("%s", number);

    Train* current = train_head;
    Train* target = NULL;
    while (current != NULL) {
        if (strcmp(current->number, number) == 0) {
            target = current;
            break;
        }
        current = current->next;
    }

    if (target == NULL) {
        printf("未找到该车次！\n");
        return;
    }

    printf("当前车次信息：\n");
    printf("车次：%s\n", target->number);
    printf("始发站：%s\n", target->start);
    printf("终点站：%s\n", target->end);
    printf("发车时间：%s\n", target->start_time);
    printf("到站时间：%s\n", target->arrive_time);
    printf("票价：%.2f\n", target->price);
    printf("剩余票数：%d\n", target->tickets);

    char choice;
    printf("是否修改始发站(Y/N)：");
    scanf(" %c", &choice);
    if (choice == 'Y' || choice == 'y') {
        printf("请输入新的始发站：");
        scanf("%s", target->start);
    }

    printf("是否修改终点站(Y/N)：");
    scanf(" %c", &choice);
    if (choice == 'Y' || choice == 'y') {
        printf("请输入新的终点站：");
        scanf("%s", target->end);
    }

    printf("是否修改发车时间(Y/N)：");
    scanf(" %c", &choice);
    if (choice == 'Y' || choice == 'y') {
        printf("请输入新的发车时间：");
        scanf("%s", target->start_time);
    }

    printf("是否修改到站时间(Y/N)：");
    scanf(" %c", &choice);
    if (choice == 'Y' || choice == 'y') {
        printf("请输入新的到站时间：");
        scanf("%s", target->arrive_time);
    }

    printf("是否修改票价(Y/N)：");
    scanf(" %c", &choice);
    if (choice == 'Y' || choice == 'y') {
        printf("请输入新的票价：");
        scanf("%f", &target->price);
    }

    printf("是否修改剩余票数(Y/N)：");
    scanf(" %c", &choice);
    if (choice == 'Y' || choice == 'y') {
        printf("请输入新的剩余票数：");
        scanf("%d", &target->tickets);
    }

    printf("火车信息修改成功！\n");
    saveData();  // 保存数据
}

// 显示所有火车信息
void showTrains() {
    Train* current = train_head;
    if (current == NULL) {
        printf("暂无火车信息！\n");
        return;
    }

    printf("所有火车信息：\n");
    while (current != NULL) {
        printf("车次：%s\n", current->number);
        printf("始发站：%s\n", current->start);
        printf("终点站：%s\n", current->end);
        printf("发车时间：%s\n", current->start_time);
        printf("到站时间：%s\n", current->arrive_time);
        printf("票价：%.2f\n", current->price);
        printf("剩余票数：%d\n", current->tickets);
        printf("------------------------\n");
        current = current->next;
    }
}

// 保存数据到文件
void saveData() {
    // 保存火车信息
    FILE* train_file = fopen("trains.dat", "w");
    if (train_file == NULL) {
        printf("无法打开火车信息文件！\n");
        return;
    }

    Train* current_train = train_head;
    while (current_train != NULL) {
        fprintf(train_file, "%s %s %s %s %s %.2f %d\n",
                current_train->number,
                current_train->start,
                current_train->end,
                current_train->start_time,
                current_train->arrive_time,
                current_train->price,
                current_train->tickets);
        current_train = current_train->next;
    }

    fclose(train_file);

    // 保存订单信息
    FILE* order_file = fopen("orders.dat", "w");
    if (order_file == NULL) {
        printf("无法打开订单信息文件！\n");
        return;
    }

    Order* current_order = order_head;
    while (current_order != NULL) {
        fprintf(order_file, "%s %s %s %s\n",
                current_order->train_number,
                current_order->passenger,
                current_order->id,
                current_order->phone);
        current_order = current_order->next;
    }

    fclose(order_file);
}

// 从文件加载数据
void loadData() {
    // 加载火车信息
    FILE* train_file = fopen("trains.dat", "r");
    if (train_file != NULL) {
        train_head = NULL;
        Train* current = NULL;

        while (!feof(train_file)) {
            Train* new_train = (Train*)malloc(sizeof(Train));
            if (fscanf(train_file, "%s %s %s %s %s %f %d",
                    new_train->number,
                    new_train->start,
                    new_train->end,
                    new_train->start_time,
                    new_train->arrive_time,
                    &new_train->price,
                    &new_train->tickets) != 7) {
                free(new_train);
                break;
            }

            new_train->next = NULL;
            if (train_head == NULL) {
                train_head = new_train;
                current = new_train;
            } else {
                current->next = new_train;
                current = new_train;
            }
        }

        fclose(train_file);
    }

    // 加载订单信息
    FILE* order_file = fopen("orders.dat", "r");
    if (order_file != NULL) {
        order_head = NULL;
        Order* current = NULL;

        while (!feof(order_file)) {
            Order* new_order = (Order*)malloc(sizeof(Order));
            if (fscanf(order_file, "%s %s %s %s",
                    new_order->train_number,
                    new_order->passenger,
                    new_order->id,
                    new_order->phone) != 4) {
                free(new_order);
                break;
            }

            new_order->next = NULL;
            if (order_head == NULL) {
                order_head = new_order;
                current = new_order;
            } else {
                current->next = new_order;
                current = new_order;
            }
        }

        fclose(order_file);
    }
}

// 显示菜单
void showMenu() {
    printf("\n===== 火车票订票系统 =====\n");
    printf("1. 添加火车信息\n");
    printf("2. 查询火车信息\n");
    printf("3. 订票\n");
    printf("4. 修改火车信息\n");
    printf("5. 显示所有火车信息\n");
    printf("6. 退出系统\n");
    printf("=========================\n");
    printf("请输入您的选择：");
}

// 主函数
int main() {
    loadData();  // 加载数据

    int choice;
    do {
        showMenu();
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                addTrain();
                break;
            case 2:
                searchTrain();
                break;
            case 3:
                bookTicket();
                break;
            case 4:
                modifyTrain();
                break;
            case 5:
                showTrains();
                break;
            case 6:
                printf("感谢使用火车票订票系统，再见！\n");
                break;
            default:
                printf("无效的选择，请重新输入！\n");
        }
    } while (choice != 6);

    return 0;
}
